package modelovectorial.persistencia;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import modelovectorial.DocumentoPDF;
import modelovectorial.Palabra;
import soporte.MySQLConnexion;
import utn.frc.tsb.utils.ValerioFritelli.HashTable.HashList;
import utn.frc.tsb.utils.ValerioFritelli.SimpleList.SimpleList;

/**
 * @project DLC Final / UTN FRC 2013
 * @date Febrero de 2013
 *
 * @author Gonzalo Arribere
 * @author Gustavo Morales
 * @author Pablo Moreno
 *
 * Esta clase se encarga de realizar todas las operaciones a la BD relacionadas
 * con los resultados de una busqueda realizada por un usuario.
 */
public class SearchResultDB {

    private final static String GET_POSTEOS = ""
            + "SELECT p.idDocumento, p.idTermino, p.tf, d.maxTF "
            + "FROM "
            + "   posteo AS p, documento as d "
            + "WHERE  "
            + "   p.idDocumento = d.idDocumento AND "
            + "   p.idTermino IN (?) ";
    
    private final static String GET_WORDS = ""
            + "SELECT terminoLimpio, nr, idTermino "
            + "FROM termino "
            + "WHERE terminoLimpio IN (?)";

    /**
     * get IdTermino, NR
     *
     * @param pQueryTerms
     * @return Hash {palabra, palabra}
     */
    public static HashList findTerminos(SimpleList pQueryTerms) {

        HashList terminos = new HashList(20);

        int length = pQueryTerms.size();

        StringBuilder queryItems = new StringBuilder("?");
        for (int i = 1; i < length; i++) {
            queryItems.append(",?");
        }
        String query = GET_WORDS.replace("?", queryItems.toString());

        Connection connection = MySQLConnexion.getConnexion();
        ResultSet result;

        Palabra word;
        try {
            PreparedStatement preparedStatment = connection.prepareStatement(query);
            System.out.println(preparedStatment);

            int Index = 1;
            String queryTerm;

            pQueryTerms.startIterator();
            while (pQueryTerms.hasNext()) {
                queryTerm = (String) pQueryTerms.next();
                preparedStatment.setString(Index, queryTerm);
                Index++;
            }

            result = preparedStatment.executeQuery();
            while (result.next()) {
                word = new Palabra(result.getInt("idTermino"), 0, result.getInt("nr"));
                terminos.put(word);
            }
            result.close();
        } catch (Exception e) {
            Logger.getLogger(SearchResultDB.class.getName()).log(Level.SEVERE, null, e);
        }
        return terminos;
    }

    /**
     * get IdDocumento, idTermino, tf
     *
     * @param pTerms
     * @returnHash {documento {
     */
    private static HashList findPosteos(HashList pQueryTerms) {
        HashList documentos = new HashList(10000);
        Palabra word;
        DocumentoPDF documento;

        int length = pQueryTerms.size();

        StringBuilder queryItems = new StringBuilder("?");
        for (int i = 1; i < length; i++) {
            queryItems.append(",?");
        }
        String query = GET_POSTEOS.replace("?", queryItems.toString());

        Connection connection = MySQLConnexion.getConnexion();
        ResultSet result;

        try {
            PreparedStatement preparedStatment = connection.prepareStatement(query);
            System.out.println(preparedStatment);

            int Index = 1;

            pQueryTerms.startIterator();
            while (pQueryTerms.hasNext()) {
                word = (Palabra) pQueryTerms.next();
                preparedStatment.setInt(Index, word.getIdPalabra());
                Index++;
            }
            System.out.println("-----------------------Executing .....");

            result = preparedStatment.executeQuery();

            System.out.println("-----------------------DONE");
            System.out.println(preparedStatment);
            while (result.next()) {
                word = (Palabra) pQueryTerms.get(new Palabra(result.getInt("idTermino")));
                documento = (DocumentoPDF) documentos.get(new DocumentoPDF(result.getInt("idDocumento")));
                if (documento == null) {
                    documento = new DocumentoPDF(result.getInt("idDocumento"), result.getInt("maxTF"));
                    documento.addPalabra(word.getIdPalabra(), result.getInt("tf"), word.getNr());
                    documentos.put(documento);
                } else {
                    documento.addPalabra(word.getIdPalabra(), result.getInt("tf"), word.getNr());
                }
            }
            result.close();
        } catch (Exception e) {
            Logger.getLogger(SearchResultDB.class.getName()).log(Level.SEVERE, null, e);
        }
        System.out.println("---HASH SIZE: " + documentos.size());
        return documentos;
    }

    /**
     * Ejecuta una consulta a la bd utilizando los terminos de una consulta que
     * se reciben por parametro.
     *
     * @param pQueryTerms Lista simple que contiene los terminos ingresados en
     * la busqueda.
     * @return un arreglo con los documentos relevantes para la busqueda
     * ingresada.
     */
    public static DocumentoPDF[] executeQuery(SimpleList pQueryTerms) {

        HashList terminos = findTerminos(pQueryTerms);
        HashList documentos = findPosteos(terminos);

        DocumentoPDF results[] = new DocumentoPDF[documentos.size()];

        documentos.startIterator();
        int index = 0;
        while (documentos.hasNext()) {
            results[index] = (DocumentoPDF) documentos.next();
            index++;
        }
        return results;
    }
}